const { rejectLimit } = require("async");
const path = require("path");
const db = require(path.join(__dirname, './../middleware/mysql/db'));
var dataresult = require(path.join(__dirname, './../module/dataresult'));
const menu = require(path.join(__dirname, './../module/menu'));
const plugm = require(path.join(__dirname, './../module/plug'))
const funcservice = require(path.join(__dirname, './../service/funcservice'))
const plugservice = require(path.join(__dirname, './../service/plugservice'))
const projectconf = require(path.join(__dirname, './../conf/project.conf'));
const UUID = require('uuid');

/**存放系统菜单 */
var _MENU_LIST=null;

let _plug_icon = 'static';
const icon_class = {vl:'class:',lg:'6'};
const icon_img = {vl:'img:',lg:'4'};

/**查询菜单-菜单维护查询 */
function queryMenu(params) {
    return new Promise((resolve, reject) => {
        try {
            let whereparam = new Array();
            if (params.id) {
                whereparam.push({ key: "id", value: params.id});
            }
            whereparam.push({key:'issuper',value: '0'});
            let sql = db.getSelect(params, menu.colum, menu.tablename, whereparam);
            db.query(sql, async function (err, rows) {
                dataresult.succSearch(rows);
                err ? reject(err) : resolve(dataresult)
            });
        } catch (err) {
            dataresult.errorExec("menuservice 程序执行异常");
            resolve(dataresult);
            console.log(err);
        }
    })
}

/**查询菜单-导航菜单 */
function queryMenuList(params) {
    return new Promise((resolve, reject) => {
        try {
            if(_MENU_LIST){
                dataresult.succSearch(_MENU_LIST);
                resolve(dataresult); 
            }else{
                let whereparam = [{ key: "enabled", value: '1' }]
                let sql = db.getSelect(params, menu.colum, menu.tablename, whereparam);
                sql = sql + " order by parentid,level";
                db.query(sql, async function (err, rows) {
                    let meunformat = changeFormat(rows);
                    let menuarr = listToTree(meunformat);
                    delFormat(menuarr);
                    let result = {router:"root",children:menuarr}
                    _MENU_LIST = result;
                    dataresult.succSearch(_MENU_LIST);
                    err ? reject(err) : resolve(dataresult)
                });
            }
        } catch (err) {
            dataresult.errorExec("menuservice 程序执行异常");
            resolve(dataresult);
            console.log(err);
        }
    })
}

/**格式化菜单，添加需用元素 */
function changeFormat(menuarr){
    let rtarray = new Array();
    Array.from(menuarr,(menu) => {
        //功能
        if(menu.menutype=='3'){
            let url = menu.url;
            if(menu.urltype=='0'){
                url =  projectconf.geturl()+ "/" + menu.url
            }
            let icon = menu.icon;
            if(icon && icon.indexOf(icon_img.vl)=='0'){
                icon = icon.substr(icon_img.lg,icon.length);
                icon = icon_img.vl+projectconf.getimgurl()+ "/" + icon;
            }
            let router = {
                'router': menu.routerpath,
                'level': menu.level,
                'name': menu.name,
                'authority':{
                    'permission': menu.role,
                    'role': menu.role
                },
                'meta': {
                    'src': url
                },
                'id': menu.id,
                'type': menu.type,
                'parentid': menu.parentid,
                'icon': icon ? icon : ''
            }
            if(menu.isshow=='0'){
                router.invisible = 'true';
            }
            rtarray.push(router);

        }else{
            let router = {
                'router': menu.routerpath,               
                'level': menu.level,
                'name': menu.name,
                'authority':{
                    'permission': menu.role,
                    'role': menu.role
                },
                'resourcepath': menu.resourcepath,
                'id': menu.id,
                'parentid': menu.parentid,
                'type': menu.type,
                'icon': menu.icon ? menu.icon : ''
            };
            
            /**
             * 前端vue 不展示菜单，只作为路由跳转的情况 
             * issuper=1 的情况下，页面不能编辑该菜单，只能初始化完成 
             * isshow=0 的情况只在此处使用，以区分初始化的菜单是否显示
             */
            // if(menu.issuper=='1' && menu.isshow=='0'){
            if(menu.isshow=='0'){
                router.invisible = 'true';
            }
            rtarray.push(router);
        }
    });
    return rtarray;
}

/**格式化菜单，删除没用的元素 */
function delFormat(menuarr){
    Array.from(menuarr,(menu) => {
        if(menu.children){
            delFormat(menu.children);
        }
        delete menu.id;
        delete menu.parentid;
        delete menu.type;
        delete menu.level;

    });
     
}

/**封装菜单格式 */
function listToTree(oldArr) {
    // console.log(oldArr);
    oldArr.forEach(element => {
        let parentId = element.parentid;
        if (parentId !== 'root') {
            oldArr.forEach(ele => {
                if (ele.id == parentId) { //当内层循环的ID== 外层循环的parendId时，（说明有children），需要往该内层id里建个children并push对应的数组；
                    if (!ele.children) {
                        ele.children = [];
                    }
                    ele.children.push(element);
                }
            });
        }
    });
    // console.log(oldArr) //此时的数组是在原基础上补充了children;
    oldArr = oldArr.filter(ele => ele.parentid === 'root'); //这一步是过滤，按树展开，将多余的数组剔除；
    // console.log(JSON.stringify(oldArr))
    return oldArr;
}

function saveMenu(params) {
    return new Promise(async function (resolve, reject) {
        try {
            if (params.funcid && params.plugid) {
                let funcid = params.funcid;
                let plugid = params.plugid;
                /**查询func */
                
                let searchfunc = { funcid: funcid, plugid: plugid }
                let funcrsdata = await funcservice.queryFunc(searchfunc);
                let funczhdata = JSON.parse(JSON.stringify(funcrsdata));
                let funcdata = funczhdata.data[0];

                /**查询plug */
                let searchplug = { id: plugid }
                let plugrsdata = await plugservice.queryPlug(searchplug);
                let plugzhdata = JSON.parse(JSON.stringify(plugrsdata));
                let plugdata = plugzhdata.data[0];

                if (!params.routerpath) {
                    params.routerpath = funcdata.name;
                }
                if (funcdata.type == '0') {
                    if(funcdata.url.indexOf('/')===0){
                        params.url = plugdata.name + "/#" + funcdata.url;
                    }else{
                        params.url = plugdata.name + "/#/" + funcdata.url;
                    }
                } else {
                    params.url = funcdata.url;
                }
                if(!params.icon){
                    let icon = funcdata.icon;
                    let hasflag = (icon.indexOf(icon_img.vl)==0)
                    if(hasflag){
                        icon = icon.substr(icon_img.lg,icon.length);
                        icon = icon_img.vl + plugdata.name+'/'+_plug_icon+'/'+icon
                    }
                    params.icon = icon;
                }
                /**内部/外部连接 */
                console.log(funcdata);
                console.log(funcdata.type);
                params.urltype = funcdata.type;
                console.log(params);
            }
            if (!params.parentid) {
                params.parentid = 'root';
            }
            if (!params.id) {
                params.id = UUID.v1();
            }
            if (!params.type) {
                params.type = '2';
            }
            if (!params.level) {
                params.level = '999'
            }
            /**处理同一节点下路由名称相同的菜单 */
            await judgeRepeatRouter(params).catch(
                err=>{
                    console.log(err,'judgeRepeatRouter');
                }
            );
            //新建菜单
            let sql = await db.getInsert(params, menu.colum, menu.tablename);
            await db.query(sql, async function (err, rows) {
                dataresult.succExec(rows);
                await updateMenuType();
                _MENU_LIST = null;
                err ? reject("数据库执行错误") : resolve(dataresult)
            });
        } catch (err) {
            console.log(err);
            reject("新增菜单时后台抛出异常");
        }
    })
}

/**处理同一菜单节点下路由相同的情况 */
function judgeRepeatRouter(params){
    /**params 默认的 parentid 和 routerpath 不为空*/
    return new Promise(async function(reject,resolve){
        let whereparam = [{key:'parentid',value:params.parentid},{key:'routerpath',value:params.routerpath}];
        let sql = await db.getSelect(null, menu.colum, menu.tablename,whereparam);
        await db.query(sql, async function (err, rows) {
            if(rows.length>0){
                var reg = /^[A-Za-z0-9_./]*\d$/
                if(reg.test(params.routerpath)){
                    let routerpath = params.routerpath;
                    let length = routerpath.length;
                    let num = routerpath.substr(length-1,length);
                    let rtnum = parseInt(num)+1;
                    params.routerpath = routerpath.substr(0,length-1) + rtnum
                }else{
                    params.routerpath = params.routerpath + '_1';
                }
                await judgeRepeatRouter(params).catch(err=>{console.log(err)});
            }
            err ? reject("数据库执行错误") : resolve(params)
        });
    })
}

/**批量修改菜单的类型（叶子节点或非叶子节点） */
async function updateMenuType() {
    return new Promise(async function (resolve, reject) {
        try {
            let changeFyz = "update menu a set a.type='2' where a.id in (" +
                "select a.id from " +
                "(select id from menu where id not in (select parentid from menu where enabled='1')  and enabled='1') a)";

            let changeYz = "update menu a set a.type='1' where a.id not in (" +
                "select a.id from " +
                "(select id from menu where id not in (select parentid from menu where enabled='1')  and enabled='1') a)";

            let sqls = new Array();
            sqls.pop(changeFyz);
            sqls.pop(changeYz);
            await db.excSqlsTranscation(sqls);
            resolve();
        } catch (err) {
            console.log(err);
            resolve("批量修改菜单类型时后台抛出异常");
        }
    });
}

/**修改菜单 */
function updateMenu(params) {
    return new Promise(async function (resolve, reject) {
        try {
            if (!params.id) {
                reject("修改的数据id为空，请检查");
            }
            let sql = await db.getUpdate(params, menu.colum, menu.tablename);
            await db.query(sql, async function (err, rows) {
                dataresult.succExec(rows);
                await updateMenuType();
                _MENU_LIST = null;
                err ? reject(err) : resolve(dataresult)
            });
        } catch (err) {
            console.log(err);
            resolve("更新菜单时后台抛出异常");
        }
    })
}

/**删除菜单 */
function deleteMenu(params) {
    return new Promise(async function (resolve, reject) {
        try {
            if (!params.id) {
                reject("删除菜单的数据id为空，请检查");
            }
            /**先检查菜单是否有子节点，如果有子节点则不能删除 */
            let sql = await db.getSelect(params, menu.colum, menu.tablename, [{ key: 'parentid', value: params.id }]);
            await db.query(sql, async function (err, rows) {
                if (rows.length > 0) {
                    dataresult.errorExec("菜单有子节点，请先删除子节点");
                    resolve(dataresult);
                } else {
                    await deleteMenuChild(params);
                }
                err ? reject(err) : resolve(dataresult)
            });
        } catch (err) {
            console.log(err);
            resolve("删除菜单时后台程序抛出异常");
        }
    })
}
/**删除菜单叶子节点 */
function deleteMenuChild(params) {
    return new Promise(async function (resolve, reject) {
        let sql = await db.getDelete(params, menu.colum, menu.tablename);
        await db.query(sql, async function (err, rows) {
            dataresult.succExec(rows);
            await updateMenuType();
            _MENU_LIST = null;
            err ? reject(err) : resolve(dataresult)
        });
    });
}

function cleanMunuCatch(){
    _MENU_LIST = null;
}

exports.queryMenu = queryMenu;
exports.saveMenu = saveMenu;
exports.updateMenu = updateMenu;
exports.deleteMenu = deleteMenu;
exports.queryMenuList = queryMenuList;
exports.cleanMunuCatch = cleanMunuCatch;